package com.db.system.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.db.system.config.DynamicDataSourceContextHolder;
import com.db.system.interfaces.DataSource;

/**
 * 数据源注解AOP拦截并切换
 * @Package: com.db.system.aop
 * @ClassName: DataSourceAspect.java
 * @Description:数据源注解AOP拦截并切换
 * 
 * @author kaifa008
 * @date 2022年1月18日 下午3:56:21
 * @Copyright: 2022 Copyright (c) 2018 LgSteel
 */
@Aspect
@Order(1)
@Component
public class DataSourceAspect {
 
//  @Pointcut("@annotation(dataSource) || @within(dataSource)")
    @Pointcut("@annotation(com.db.system.interfaces.DataSource)")
    public void dataSourcePointCut() {
    }
 
    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        DataSource dataSource = getDataSource(point);
        if (dataSource != null) {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value());
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }
 
    /**
     * 获取需要切换的数据源
     * @param point
     * @return
     */
    public DataSource getDataSource(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (dataSource != null) {
            return dataSource;
        }
        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
}

